package com.music.note_android.ui.editor

import android.view.MotionEvent
import kotlin.math.max
import kotlin.math.min
import kotlin.math.pow

/**
 * 压感处理器
 * 负责处理压感输入、压感校准、压感优化和压感响应
 */
class PressureHandler {
    
    // 压感配置
    private var pressureSensitivity = 1.0f // 压感灵敏度
    private var minPressure = 0.1f // 最小压感值
    private var maxPressure = 1.0f // 最大压感值
    private var pressureCurve = 1.0f // 压感曲线指数
    
    // 压感校准
    private var pressureOffset = 0.0f // 压感偏移
    private var pressureScale = 1.0f // 压感缩放
    private var isCalibrated = false // 是否已校准
    
    // 压感平滑
    private var enableSmoothing = true // 启用压感平滑
    private var smoothingFactor = 0.3f // 平滑因子
    private var lastPressure = 0.0f // 上一次压感值
    private val pressureHistory = mutableListOf<Float>() // 压感历史
    private val maxHistorySize = 5 // 最大历史记录数
    
    // 压感预测
    private var enablePrediction = true // 启用压感预测
    private var predictionStrength = 0.2f // 预测强度
    
    // 设备特性
    private var deviceSupportsPressure = false // 设备是否支持压感
    private var deviceMaxPressure = 1.0f // 设备最大压感值
    private var deviceMinPressure = 0.0f // 设备最小压感值
    
    // 压感统计
    private var totalPressureEvents = 0L
    private var averagePressure = 0.0f
    private var maxRecordedPressure = 0.0f
    private var minRecordedPressure = 1.0f
    
    // 压感变化监听器
    private var onPressureChangeListener: ((Float) -> Unit)? = null
    
    /**
     * 初始化压感处理器
     */
    fun initialize() {
        // 检测设备压感支持
        detectPressureSupport()
        
        // 重置统计信息
        resetStatistics()
        
        // 初始化压感历史
        pressureHistory.clear()
    }
    
    /**
     * 检测设备压感支持
     */
    private fun detectPressureSupport() {
        // 这里可以根据设备型号或其他方式检测压感支持
        // 暂时假设所有设备都支持基本压感
        deviceSupportsPressure = true
        deviceMaxPressure = 1.0f
        deviceMinPressure = 0.0f
    }
    
    /**
     * 处理压感输入
     */
    fun processPressure(event: MotionEvent): Float {
        // 获取原始压感值
        val rawPressure = getRawPressure(event)
        
        // 应用校准
        val calibratedPressure = applyCalibratedPressure(rawPressure)
        
        // 应用压感曲线
        val curvedPressure = applyPressureCurve(calibratedPressure)
        
        // 应用平滑
        val smoothedPressure = if (enableSmoothing) {
            applySmoothPressure(curvedPressure)
        } else {
            curvedPressure
        }
        
        // 应用预测
        val finalPressure = if (enablePrediction) {
            applyPressurePrediction(smoothedPressure)
        } else {
            smoothedPressure
        }
        
        // 更新统计信息
        updateStatistics(finalPressure)
        
        // 更新历史记录
        updatePressureHistory(finalPressure)
        
        // 通知压感变化监听器
        onPressureChangeListener?.invoke(finalPressure)
        
        return finalPressure
    }
    
    /**
     * 获取原始压感值
     */
    private fun getRawPressure(event: MotionEvent): Float {
        return if (deviceSupportsPressure) {
            // 从MotionEvent获取压感值
            val pressure = event.pressure
            
            // 确保压感值在有效范围内
            max(deviceMinPressure, min(deviceMaxPressure, pressure))
        } else {
            // 设备不支持压感时返回默认值
            0.5f
        }
    }
    
    /**
     * 应用压感校准
     */
    private fun applyCalibratedPressure(rawPressure: Float): Float {
        return if (isCalibrated) {
            val calibrated = (rawPressure + pressureOffset) * pressureScale
            max(0.0f, min(1.0f, calibrated))
        } else {
            rawPressure
        }
    }
    
    /**
     * 应用压感曲线
     */
    private fun applyPressureCurve(pressure: Float): Float {
        // 使用指数曲线调整压感响应
        val curved = pressure.pow(pressureCurve)
        
        // 应用灵敏度
        val sensitive = curved * pressureSensitivity
        
        // 限制在最小最大值范围内
        return max(minPressure, min(maxPressure, sensitive))
    }
    
    /**
     * 应用压感平滑
     */
    private fun applySmoothPressure(pressure: Float): Float {
        return if (lastPressure == 0.0f) {
            // 第一次输入，直接使用当前值
            lastPressure = pressure
            pressure
        } else {
            // 使用指数移动平均进行平滑
            val smoothed = lastPressure * (1 - smoothingFactor) + pressure * smoothingFactor
            lastPressure = smoothed
            smoothed
        }
    }
    
    /**
     * 应用压感预测
     */
    private fun applyPressurePrediction(pressure: Float): Float {
        if (pressureHistory.size < 2) {
            return pressure
        }
        
        // 计算压感变化趋势
        val recent = pressureHistory.takeLast(2)
        val trend = recent[1] - recent[0]
        
        // 应用预测
        val predicted = pressure + trend * predictionStrength
        
        // 限制预测结果在合理范围内
        return max(minPressure, min(maxPressure, predicted))
    }
    
    /**
     * 更新压感历史
     */
    private fun updatePressureHistory(pressure: Float) {
        pressureHistory.add(pressure)
        
        // 限制历史记录大小
        if (pressureHistory.size > maxHistorySize) {
            pressureHistory.removeAt(0)
        }
    }
    
    /**
     * 更新统计信息
     */
    private fun updateStatistics(pressure: Float) {
        totalPressureEvents++
        
        // 更新平均值
        averagePressure = (averagePressure * (totalPressureEvents - 1) + pressure) / totalPressureEvents
        
        // 更新最大最小值
        maxRecordedPressure = max(maxRecordedPressure, pressure)
        minRecordedPressure = min(minRecordedPressure, pressure)
    }
    
    /**
     * 校准压感
     */
    fun calibratePressure(lightPressure: Float, heavyPressure: Float) {
        if (lightPressure >= heavyPressure) {
            return // 无效的校准数据
        }
        
        // 计算校准参数
        val range = heavyPressure - lightPressure
        pressureScale = 1.0f / range
        pressureOffset = -lightPressure
        
        isCalibrated = true
    }
    
    /**
     * 重置校准
     */
    fun resetCalibration() {
        pressureOffset = 0.0f
        pressureScale = 1.0f
        isCalibrated = false
    }
    
    /**
     * 设置压感灵敏度
     */
    fun setPressureSensitivity(sensitivity: Float) {
        pressureSensitivity = max(0.1f, min(3.0f, sensitivity))
    }
    
    /**
     * 设置压感范围
     */
    fun setPressureRange(min: Float, max: Float) {
        if (min < max && min >= 0.0f && max <= 1.0f) {
            minPressure = min
            maxPressure = max
        }
    }
    
    /**
     * 设置压感曲线
     */
    fun setPressureCurve(curve: Float) {
        pressureCurve = max(0.1f, min(3.0f, curve))
    }
    
    /**
     * 设置平滑参数
     */
    fun setSmoothingParameters(enabled: Boolean, factor: Float) {
        enableSmoothing = enabled
        smoothingFactor = max(0.0f, min(1.0f, factor))
    }
    
    /**
     * 设置预测参数
     */
    fun setPredictionParameters(enabled: Boolean, strength: Float) {
        enablePrediction = enabled
        predictionStrength = max(0.0f, min(1.0f, strength))
    }
    
    /**
     * 获取压感配置
     */
    fun getPressureConfiguration(): PressureConfiguration {
        return PressureConfiguration(
            sensitivity = pressureSensitivity,
            minPressure = minPressure,
            maxPressure = maxPressure,
            curve = pressureCurve,
            smoothingEnabled = enableSmoothing,
            smoothingFactor = smoothingFactor,
            predictionEnabled = enablePrediction,
            predictionStrength = predictionStrength,
            isCalibrated = isCalibrated
        )
    }
    
    /**
     * 设置压感配置
     */
    fun setPressureConfiguration(config: PressureConfiguration) {
        pressureSensitivity = config.sensitivity
        minPressure = config.minPressure
        maxPressure = config.maxPressure
        pressureCurve = config.curve
        enableSmoothing = config.smoothingEnabled
        smoothingFactor = config.smoothingFactor
        enablePrediction = config.predictionEnabled
        predictionStrength = config.predictionStrength
        isCalibrated = config.isCalibrated
    }
    
    /**
     * 获取压感统计信息
     */
    fun getPressureStatistics(): PressureStatistics {
        return PressureStatistics(
            totalEvents = totalPressureEvents,
            averagePressure = averagePressure,
            maxPressure = maxRecordedPressure,
            minPressure = minRecordedPressure,
            currentPressure = lastPressure,
            deviceSupported = deviceSupportsPressure,
            isCalibrated = isCalibrated
        )
    }
    
    /**
     * 重置统计信息
     */
    fun resetStatistics() {
        totalPressureEvents = 0L
        averagePressure = 0.0f
        maxRecordedPressure = 0.0f
        minRecordedPressure = 1.0f
        lastPressure = 0.0f
        pressureHistory.clear()
    }
    
    /**
     * 检查设备是否支持压感
     */
    fun isDevicePressureSupported(): Boolean {
        return deviceSupportsPressure
    }
    
    /**
     * 获取推荐的压感设置
     */
    fun getRecommendedSettings(): PressureConfiguration {
        return if (deviceSupportsPressure) {
            // 支持压感的设备推荐设置
            PressureConfiguration(
                sensitivity = 1.2f,
                minPressure = 0.1f,
                maxPressure = 0.9f,
                curve = 1.2f,
                smoothingEnabled = true,
                smoothingFactor = 0.3f,
                predictionEnabled = true,
                predictionStrength = 0.2f,
                isCalibrated = false
            )
        } else {
            // 不支持压感的设备推荐设置
            PressureConfiguration(
                sensitivity = 1.0f,
                minPressure = 0.3f,
                maxPressure = 0.7f,
                curve = 1.0f,
                smoothingEnabled = false,
                smoothingFactor = 0.0f,
                predictionEnabled = false,
                predictionStrength = 0.0f,
                isCalibrated = false
            )
        }
    }
    
    /**
     * 设置压感变化监听器
     */
    fun setOnPressureChangeListener(listener: (Float) -> Unit) {
        onPressureChangeListener = listener
    }
    
    /**
     * 压感配置数据类
     */
    data class PressureConfiguration(
        val sensitivity: Float,
        val minPressure: Float,
        val maxPressure: Float,
        val curve: Float,
        val smoothingEnabled: Boolean,
        val smoothingFactor: Float,
        val predictionEnabled: Boolean,
        val predictionStrength: Float,
        val isCalibrated: Boolean
    )
    
    /**
     * 压感统计信息数据类
     */
    data class PressureStatistics(
        val totalEvents: Long,
        val averagePressure: Float,
        val maxPressure: Float,
        val minPressure: Float,
        val currentPressure: Float,
        val deviceSupported: Boolean,
        val isCalibrated: Boolean
    )
}